package com.publishsystem.util;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.LongSerializationPolicy;
import com.publishsystem.util.page.ResultInfo;
import org.apache.log4j.Logger;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Method;

/**
 * BaseServlet用来作为其它Servlet的父类
 * 一个类多个请求处理方法，每个请求处理方法的原型与service相同！ 原型 = 返回值类型 + 方法名称 + 参数列表
 */
@SuppressWarnings("serial")
public class BaseServlet extends HttpServlet {

    private static final Logger logger = Logger.getLogger(BaseServlet.class);

    @Override
    public void service(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        /**
         * 1. 获取method参数，它是用户想调用的方法 2. 把方法名称变成Method类的实例对象 3. 通过invoke()来调用这个方法
         */
        String methodName = request.getParameter("method");
        Method method = null;
        /**
         * 2. 通过方法名称获取Method对象
         */
        try {
            method = this.getClass().getMethod(methodName,
                    HttpServletRequest.class, HttpServletResponse.class);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getMessage());
            writeJson(response, ResultInfo.fail("您要调用的方法：" + methodName + "它不存在！"));
        }
        /**
         * 3. 通过method对象来调用它
         */
        try {
            Object result = method.invoke(this, request, response);
            //这里可以判断返回值类型
            if (result != null) {
                if (result instanceof String) {
                    String resultStr = (String) result;
                    if (!resultStr.trim().isEmpty()) {//如果请求处理方法返回不为空
                        int index = resultStr.indexOf(":");//获取第一个冒号的位置
                        if (index == -1) {//如果没有冒号，使用转发
                            request.getRequestDispatcher(resultStr).forward(request, response);
                        } else {//如果存在冒号
                            String start = resultStr.substring(0, index);//分割出前缀
                            String path = resultStr.substring(index + 1);//分割出路径
                            if (start.equals("f")) {//前缀为f表示转发
                                request.getRequestDispatcher(path).forward(request, response);
                            } else if (start.equals("r")) {//前缀为r表示重定向
                                response.sendRedirect(request.getContextPath() + path);
                            }
                        }
                    }
                } else if (result instanceof ResultInfo) {
                    writeJson(response, result);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(e.getMessage());
            //可以添加自定义异常处理类
            writeJson(response,ResultInfo.fail(e.getMessage()));
        }
    }

    /**
     * 将map转换成json并发送给调用者
     *
     */
    public void writeJson(HttpServletResponse response,
                          Object params) throws IOException {
        GsonBuilder gb = new GsonBuilder().serializeNulls().setDateFormat("yyyy-MM-dd HH:mm:ss");
        gb.setLongSerializationPolicy(LongSerializationPolicy.STRING);
        Gson gson = gb.create();
        //response.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=UTF-8");//处理响应编码
        PrintWriter writer = response.getWriter();
        writer.write(gson.toJson(params));
        writer.flush();
        writer.close();
    }
}
